package gestionmagasins_aspectj_junit_patterns.aspect;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

import gestionmagasins_aspectj_junit_patterns.model.*;
import gestionmagasins_aspectj_junit_patterns.test.*;
import gestionmagasins_aspectj_junit_patterns.GestionMagasinsMain;

import org.aspectj.lang.Aspects;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.CodeSignature;
import org.hamcrest.core.Is;


public aspect LoggingAspect extends Aspects 
{
    Logger logger;
    static private FileHandler fileTxt;
    static private SimpleFormatter formatterTxt;
    static boolean isLoaded = false;


    before() : execution(* *.*(..)) //Pour initialiser le logger avant l'appel de la premiere methode, peut importe laquelle
    {    
    	if(!isLoaded)//Pour eviter que le logger soit initialiser a chaque fois
    	{
    		isLoaded = true;
    		
	        logger = Logger.getLogger("LOG");
	
	        logger.setLevel(Level.INFO);
	        
	        if(fileTxt == null)
	        {
		        try 
		        {   
		        	String currentDate = new SimpleDateFormat("yyyy-MM-dd HH'h'mm'm'ss's'").format(new Date());
					fileTxt = new FileHandler("Logging_"+currentDate+".txt");	
				} 
		        catch (SecurityException | IOException e) 
		        {
					e.printStackTrace();
				}
		
		        // create a TXT formatter
		        formatterTxt = new SimpleFormatter();
		        fileTxt.setFormatter(formatterTxt);
		        logger.addHandler(fileTxt);
	        }
    	}

    }
    
    pointcut loggedLogin(Usager user) : 	call(* Securite.login(..)) && args(user);
	after(Usager user) : loggedLogin(user) 
	{    	
		String msg = String.format("\n\tConnexion de l'usager : %s", user.toString()) ;
		
		logger.info(msg);
	}
	
	pointcut loggedLogout() : 	call(* Securite.logout(..));
	before() : loggedLogout() 
	{    	
		String msg = String.format("\n\tDéconnexion de l'usager : %s", Securite.getInstance().getCurrentUsager().toString()) ;
		
		logger.info(msg);
	}

    pointcut loggedAdd(Object elem) : 	call(void Catalogue*.add*(..)) && args(elem) 
    									&& !withincode(* *Test.*(..));                                                 
    after(Object elem) : loggedAdd(elem) 
    {
    	String msg = "Ajout de l'�l�ment '%s': %s au %s";
    	
    	loggedAllCatalogue(msg, elem,thisJoinPoint);
    }
    
    
    pointcut loggedDelete(Object elem) : 	call(* Catalogue*.delete*(..)) && args(elem) 
											&& !withincode(* *Test.*(..));
    after(Object elem) : loggedDelete(elem) 
    {    	
    	String msg = "Suppression de l'�l�ment '%s': %s au %s";
    	
    	loggedAllCatalogue(msg, elem,thisJoinPoint);
    }
    
    private String getCleanName(String fullname)
    {
    	String[] cleanName = fullname.split("[.]");
    	
    	return cleanName[cleanName.length - 1];
    }
    
    private void loggedAllCatalogue(String msgLog, Object elem,JoinPoint thisjoinpoint)
    {
    	if(elem instanceof Vente)
    	{
    		elem = (Vente)elem;
    	}
    	else if(elem instanceof Client)
    	{
    		elem = (Client)elem;
    	}
    	else if(elem instanceof Article)
    	{
    		elem = (Article)elem;
    	}
    	else if(elem instanceof Usager)
    	{
    		elem = (Usager)elem;
    	}
    	
    	msgLog = String.format(msgLog,getCleanName(elem.getClass().getName().toString()),elem.toString(),getCleanName(thisjoinpoint.getSignature().getDeclaringTypeName()));
        
    	logger.info("\n\t"+msgLog);
    }
}
